const XlsxPopulate = require('xlsx-populate');

;exports = module.exports = (function () {

    function Exportor() {};

    function Cell(str) {
        var me = this,
            chArr;
        str = str ? (str + '').toUpperCase() : 'A1';
        this._colIdx = str.split(/\d+/)[0]; // 'A'
    
        chArr = this._colIdx.split('');
        this._colIdxNum = 1;
        chArr.forEach(function(c, i) {
            me._colIdxNum += (c.charCodeAt() - 64) * (Math.pow(26, chArr.length - i - 1)); // 1
        });

        this._rowIdx = +str.split(/[a-z | A-Z]+/)[1]; // 1
    };
    
    Cell.prototype.getRowIdx = function() {
        return this._rowIdx;
    };
    
    Cell.prototype.getColIdx = function() {
        return this._colIdx;
    };
    
    Cell.prototype.getColIdxNumber = function() {
        return this._colIdxNum;
    };
    
    Cell.prototype.toString = function() {
        return this._colIdx + this._rowIdx;
    }
    
    Cell.prototype.addCol = function(num) {
        var ch = [];
        var s, x, y;
        num = +num;
        this._colIdxNum = this._colIdxNum + num;
        s = this._colIdxNum
        do {
            x = ~~(s / 26);
            y = s % 26;
            if(y === 0) {
                ch.unshift('Z');
                s = x - 1;
            }else {
                ch.unshift(String.fromCharCode(64 + y));
                s = x;
            }
        }while(s > 0);
    
        this._colIdx = ch.join('');
        return this;
    }
    
    Cell.prototype.addRow = function(num) {
        num = +num;
        this._rowIdx += num;
        return this;
    }

    Exportor.prototype.init = function (json, wbname) {
        this._json = json;
        this._filename = wbname;
        return this._generateWorkbookBlob().then(blob => {
            this._blob = blob;
            return this;
        });
    };
    
    Exportor.prototype._getWorkbook = function() {
        return XlsxPopulate.fromBlankAsync();
    };

    Exportor.prototype._generateWorkbookBlob = function() {
        var me = this;
        return this._getWorkbook()
            .then(function(workbook) {
                return me._fullWorkbook(workbook, me._json);
            });
    };

    Exportor.prototype._fullWorkbook = function(workbook, json) {
        var index = 0,
            sheetData,
            sheetName,
            header,
            columns,
            clen,
            rows,
            sheet,
            cell,
            r, startCell, endCell, columnDatas, sheet_columns, i;
        do{
            sheetData = json.sheets[index];
            sheetName = sheetData.name;
            header = sheetData.header;
            columns = sheetData.columns;
            clen = columns.length;
            rows = sheetData.rows;
            cell = new Cell('A1');

            if(workbook.sheets().length - 1 < index) {
                sheet = workbook.addSheet(sheetName)
            }else {
                sheet = workbook.sheet(index).name(sheetName);
            }

            if(header) {
                startCell = cell;
                endCell = new Cell('A1').addCol(clen - 2);
                r = sheet.range(startCell + ":" + endCell).merged(true);
                r.value(header);
                r.style({ fill: '70AD47', fontColor: 'ffffff', bold: true, horizontalAlignment: 'center', bottomBorder: true, bottomBorderColor: 'EAEAEA' });
                cell.addRow(1);
            }

            if(clen > 0) {
                columnDatas = [columns.map(function(c) {
                    return c.name;
                })];
                r = sheet.range(cell + ":" + new Cell(cell).addCol(clen - 2));
                r.value(columnDatas);
                sheet_columns = r.cells()[0].map(function(c) {
                    return c.column();
                });
                for(i = 0; i < columns.length; i++) {
                    if(sheet_columns[i]) {
                        sheet_columns[i].width(columns[i].width);
                    }
                }
                r.style({ fill: '70AD47', fontColor: 'ffffff', bold: true, horizontalAlignment: 'center', rightBorder: true, rightBorderColor: 'EAEAEA' });
                cell.addRow(1);
            }
            if(rows.length > 0) {
                r = sheet.range(cell + ":" + new Cell(cell).addRow(rows.length - 1).addCol(clen - 2));
                r.value(rows);
                r.style('fill', function(cell, ri, ci, range) {
                    return (ri&1) === 0 ? 'C6E0B4' : 'A9D08E';
                })
                .style({ rightBorder: true, rightBorderColor: 'EAEAEA' });
            }

            index++;
        }while(!!json.sheets[index]);
        
        return workbook.outputAsync();
    };

    Exportor.prototype.export = function() {
        var url, a;
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(this._blob, this._filename + ".xlsx");
        } else {
            url = window.URL.createObjectURL(this._blob);
            a = document.createElement("a");
            
            document.body.appendChild(a);
            a.href = url;
            a.download = this._filename + ".xlsx";
            a.click();
            window.URL.revokeObjectURL(url);
            document.body.removeChild(a);
        }
    };

    return Exportor;
})();